﻿using System.IO;
using System;
using Microsoft.VisualStudio.SharePoint;
using Microsoft.VisualStudio.SharePoint.Deployment;
using Microsoft.VisualStudio.SharePoint.Packages;
using System.ComponentModel.Composition;
using System.Linq;
using System.DirectoryServices;

using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Xml;
using SPVSX.Common;
using EnvDTE;
using EnvDTE80;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;

namespace SPVSX.DeploymentExtensions.QuickDeployment
{
    /// <summary>
    /// TODO: COMMENT
    /// 
    /// This code is a WIP and is in need of improved commenting, exception handling, and potentially
    /// factoring.  Please be nice.
    /// 
    /// Though this code is Open Source, in good faith it is requested that you consult the original author(s)
    /// before changing or re-using it for any public endeavour intended to provide similar functionality, or
    /// to fix simple bugs.  In other words, if you want to create SPVSX2, please let us know first.
    /// </summary>
    /// <remarks>@author Matt Smith, http://blog.mattsmith.co.nz</remarks>
    public class SharePointProjectItemArtefact : QuickCopyableSharePointArtefact
    {
        private ISharePointProjectItem item = null;
        private IEnumerable<QuickCopyableSharePointArtefact> kids = null;
        private Dictionary<string, string> tokens = null;

        public SharePointProjectItemArtefact(ISharePointProjectItem item)
        {
            this.item = item;
        }

        public override IEnumerable<QuickCopyableSharePointArtefact> ChildArtefacts
        {
            get
            {
                if (kids == null)
                {
                    List<QuickCopyableSharePointArtefact> children = new List<QuickCopyableSharePointArtefact>();

                    foreach (ISharePointProjectItemFile spiFile in item.Files.Where(file => file.DeploymentType != DeploymentType.NoDeployment))
                    {
                        children.Add(new SharePointProjectItemFileArtefact(spiFile));
                    }

                    kids = children;
                }
                return kids;
            }
        }

        public override bool IsPackaged(ISharePointProjectService service)
        {
            return item.IsPartOfAnyProjectPackage(service);
        }

        public override bool IsPackaged(ISharePointProject project)
        {
            return item.IsPartOfProjectPackage(project);
        }

        public override IEnumerable<ISharePointProject> GetPackagedProjects(ISharePointProjectService service)
        {
            return item.GetProjectsWhereInPackage(service);
        }

        public override Dictionary<string, string> Tokens
        {
            get
            {
                if (tokens == null)
                {
                    tokens = new Dictionary<string, string>();
                    tokens.Add("SharePoint.ProjectItem.Name", item.Name);
                    
                    // TODO
                    //tokens.Add("SharePoint.Type.<GUID>.AssemblyQualifiedName", "TODO");
                    //tokens.Add("SharePoint.Type.<GUID>.FullName", "TODO");     
                }

                return tokens;
            }
        }

        public override void QuickCopy(SharePointPackageArtefact packageProject, bool requiresQuickPackage)
        {
            // We are directly deploying just this SPI and have not been called by our parent.
            // An SPI may be included in multiple features, or be against the project directly.
            if (item.IsDirectPartOfProjectPackage(packageProject.Project))
            {
                // Pass in the package itself as the parent.
                this.QuickCopy(packageProject, packageProject, requiresQuickPackage);
            }
            else
            {
                // The SPI may be included in multiple features in the project in context.
                foreach (ISharePointProjectFeature feature in item.GetFeaturesWhereInPackage(packageProject.Project))
                {
                    QuickCopyableSharePointArtefact parent = new SharePointProjectFeatureArtefact(feature);
                    this.QuickCopy(packageProject, parent, requiresQuickPackage);
                }
            }
        }

        public override void QuickCopy(SharePointPackageArtefact packageProject, QuickCopyableSharePointArtefact parentArtefact, bool requiresQuickPackage)
        {
            if (parentArtefact == null)
            {
                throw new NotSupportedException();
            }
            else if (parentArtefact is SharePointProjectFeatureArtefact || parentArtefact is SharePointPackageArtefact)
            {
                OutputWindowLogger.Instance.WriteLine("------ Quick Copying SPI in " + (parentArtefact is SharePointPackageArtefact ? "Package" : "Feature") + ": " + item.Name + " ------", LogCategory.Status);

                foreach (SharePointProjectItemFileArtefact spiFile in this.ChildArtefacts.Select(ca => ca as SharePointProjectItemFileArtefact))
                {
                    spiFile.QuickCopy(packageProject, parentArtefact, requiresQuickPackage);
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
    }
}